package config

import (
	"log"
	"os"
	"sync"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var (
	once   sync.Once
	Config *AppConfig
)

type AppConfig struct {
	App struct {
		Port int `mapstructure:"port"`
	} `mapstructure:"app"`

	Database struct {
		Host     string `mapstructure:"host"`
		Port     int    `mapstructure:"port"`
		User     string `mapstructure:"user"`
		Password string `mapstructure:"password"`
		Name     string `mapstructure:"name"`
	} `mapstructure:"database"`
}

func Init(configPath string) {
	once.Do(func() {
		v := viper.New()
		v.SetConfigFile(configPath)
		v.SetConfigType("yaml")

		if err := v.ReadInConfig(); err != nil {
			log.Fatalf("Failed to read config file: %v", err)
		}

		v.WatchConfig()
		v.OnConfigChange(func(e fsnotify.Event) {
			log.Println("Config file changed:", e.Name)
			if err := v.Unmarshal(&Config); err != nil {
				log.Printf("Failed to reload config: %v", err)
			}
		})

		if err := v.Unmarshal(&Config); err != nil {
			log.Fatalf("Failed to unmarshal config: %v", err)
		}

		loadEnv(v)

		log.Println("Config initialized successfully")
	})
}

func loadEnv(v *viper.Viper) {
	if port := os.Getenv("APP_PORT"); port != "" {
		v.Set("app.port", port)
	}
	if env := os.Getenv("APP_ENV"); env != "" {
		v.Set("app.env", env)
	}
}
